//============================================================================================
/**
 * @file	zkn2_list.c
 * @brief	金銀図鑑画面 リスト作成関連
 * @author	Hiroyuki Nakamura
 * @date	08.08.28
 */
//============================================================================================
#include "common.h"

#include "poketool/poke_number.h"
#include "zkn_data/zukan_data.naix"

#include "zkn2_main.h"
#include "zkn2_list.h"
#include "application/zukanlist/zkn_gira.h"


//============================================================================================
//	定数定義
//============================================================================================
// ポケモンリストデータ
enum{
	// 本体
	ZKN_SORTDATA_ZENKOKU = 0,	// 全国図鑑
	ZKN_SORTDATA_JOHTO,			// ジョウト図鑑

	// ソートデータ
	ZKN_SORTDATA_AIUEO,
	ZKN_SORTDATA_HEAVY,
	ZKN_SORTDATA_LIGHT,
	ZKN_SORTDATA_TALL,
	ZKN_SORTDATA_SMALL,

	// 名前検索
	ZKN_SORTDATA_NAME_A,

	// タイプ検索
	ZKN_SORTDATA_TYPE_NORMAL = ZKN_SORTDATA_NAME_A + ZKN2LIST_SEARCH_NAME_NONE,
	ZKN_SORTDATA_TYPE_BATTLE,
	ZKN_SORTDATA_TYPE_HIKOU,
	ZKN_SORTDATA_TYPE_POISON,
	ZKN_SORTDATA_TYPE_JIMEN,
	ZKN_SORTDATA_TYPE_IWA,
	ZKN_SORTDATA_TYPE_MUSHI,
	ZKN_SORTDATA_TYPE_GHOST,
	ZKN_SORTDATA_TYPE_METAL,
	ZKN_SORTDATA_TYPE_FIRE,
	ZKN_SORTDATA_TYPE_WATER,
	ZKN_SORTDATA_TYPE_KUSA,
	ZKN_SORTDATA_TYPE_ELECTRIC,
	ZKN_SORTDATA_TYPE_SP,
	ZKN_SORTDATA_TYPE_KOORI,
	ZKN_SORTDATA_TYPE_DRAGON,
	ZKN_SORTDATA_TYPE_AKU,

	// 形検索
	ZKN_SORTDATA_FORM_FOUR_LEGS,
	ZKN_SORTDATA_FORM_TWO_LEGS,
	ZKN_SORTDATA_FORM_TAIL,
	ZKN_SORTDATA_FORM_HARABAI,
	ZKN_SORTDATA_FORM_FOUR_WING,
	ZKN_SORTDATA_FORM_TWO_WING,
	ZKN_SORTDATA_FORM_HAITSUKUBARI,
	ZKN_SORTDATA_FORM_STRAIGHT,
	ZKN_SORTDATA_FORM_ARM,
	ZKN_SORTDATA_FORM_LEGS,
	ZKN_SORTDATA_FORM_MANY_LEGS,
	ZKN_SORTDATA_FORM_WATER,
	ZKN_SORTDATA_FORM_CIRCLE,
	ZKN_SORTDATA_FORM_COMP,

	ZKN_SORTDATA_MAX
};


//============================================================================================
//	プロトタイプ宣言
//============================================================================================
static u16 * SortDataLoad( u32 idx, u32 * max );
static void SeeMonsDataMake( u16 * make, u32 * cnt, const ZUKAN_WORK * sv, const u16 * list, u32 num );
static void ListMakeFinal( ZKN2_LIST * list, const ZUKAN_WORK * sv, const u16 * tbl, int num );
static void ListSort( u32 type, u16 * make, u32 * cnt, const u16 * list, u32 num, const ZUKAN_WORK * sv );
static void NameSearch( u32 type, u16 * make, u32 * cnt, const u16 * list, u32 num, const ZUKAN_WORK * sv );
static void TypeSearch( u32 type, u16 * make, u32 * cnt, const u16 * list, int num, const ZUKAN_WORK * sv );
static void FormSearch( u32 type, u16 * make, u32 * cnt, const u16 * list, u32 num, const ZUKAN_WORK * sv );
static void ListSearch( u16 * make, u32 * cnt, const u16 * list, u32 list_num, const u16 * sarch, u32 sarch_num, BOOL see_ok_flg, const ZUKAN_WORK * sv );
static void AreaSearch( ZKN2_WORK * wk, u32 type, u16 * make, u32 * cnt, const u16 * list, u32 num, const ZUKAN_WORK * sv );
static void HeightSearch(
				ZKN2_WORK * wk, u16 low, u16 hi,
				u16 * make, u32 * cnt, const u16 * list, u32 num, const ZUKAN_WORK * sv );
static void WeightSearch(
				ZKN2_WORK * wk, u16 low, u16 hi,
				u16 * make, u32 * cnt, const u16 * list, u32 num, const ZUKAN_WORK * sv );
static u32 GetSearchIDType( u32 p );


//============================================================================================
//	グローバル変数
//============================================================================================

// タイプテーブル
static const u32 SearchTypeTbl[] = {
	ZKN2LIST_SEARCH_TYPE_AKU,
	ZKN2LIST_SEARCH_TYPE_IWA,
	ZKN2LIST_SEARCH_TYPE_SP,
	ZKN2LIST_SEARCH_TYPE_BATTLE,

	ZKN2LIST_SEARCH_TYPE_KUSA,
	ZKN2LIST_SEARCH_TYPE_KOORI,
	ZKN2LIST_SEARCH_TYPE_GHOST,
	ZKN2LIST_SEARCH_TYPE_JIMEN,

	ZKN2LIST_SEARCH_TYPE_ELECTRIC,
	ZKN2LIST_SEARCH_TYPE_POISON,
	ZKN2LIST_SEARCH_TYPE_DRAGON,
	ZKN2LIST_SEARCH_TYPE_NORMAL,

	ZKN2LIST_SEARCH_TYPE_METAL,
	ZKN2LIST_SEARCH_TYPE_HIKOU,
	ZKN2LIST_SEARCH_TYPE_FIRE,
	ZKN2LIST_SEARCH_TYPE_WATER,

	ZKN2LIST_SEARCH_TYPE_MUSHI,
	ZKN2LIST_SEARCH_TYPE_NONE,
};



//--------------------------------------------------------------------------------------------
/**
 *	ポケモンリストテーブル作成
 *
 *	@param	wk			図鑑画面ワーク
 *	@param	mode		図鑑モード
 *	@param	sort		ソートタイプ
 *	@param	name		名前検索タイプ
 *	@param	type1		タイプ１検索タイプ
 *	@param	type2		タイプ２検索タイプ
 *	@param	hLow		高さ（低）
 *	@param	hHi			高さ（高）
 *	@param	wLow		重さ（低）
 *	@param	wHi			重さ（高）
 *	@param	area		地域
 *	@param	form		形検索タイプ
 *
 *	@retval	"TRUE = 作成成功"
 *	@retval	"FALSE = 作成結果リストが０個"
 *
 *
 *	zkn_glbdata.c の ZKN_GLBDATA_PokeListTblMake_DummyListCutFlg() を参考
 */
//--------------------------------------------------------------------------------------------
BOOL ZKN2LIST_MonsListTblMake(
		ZKN2_WORK * wk,
		u32 mode,
		u32 sort,
		u32 name,
		u32 type1,
		u32 type2,
		u32	hLow,
		u32	hHi,
		u32	wLow,
		u32	wHi,
		u32	area,
		u32 form )
{
	u16 * list;
	u16 * make0;
	u16 * make1;
	u32	list_siz;
	u32	make0_cnt;
	u32	make1_cnt;
	BOOL ret;

	// 作成先初期化
	MI_CpuClear32( &wk->mons_list, sizeof(ZKN2_LIST) );

	// バッファ領域を確保
	make0 = sys_AllocMemoryLo( HEAPID_ZUKAN, sizeof(u16) * ZKN2_POKELIST_TBL_MAX );
	GF_ASSERT( make0 );
	memset( make0, 0, sizeof(u16) * ZKN2_POKELIST_TBL_MAX );
	make0_cnt = 0;
	make1 = sys_AllocMemoryLo( HEAPID_ZUKAN, sizeof(u16) * ZKN2_POKELIST_TBL_MAX );
	GF_ASSERT( make1 );
	memset( make1, 0, sizeof(u16) * ZKN2_POKELIST_TBL_MAX );
	make1_cnt = 0;

	// 各図鑑モードのリストデータ読み込み
	if( mode == ZKN2_MODE_JOHTO ){
		list = SortDataLoad( ZKN_SORTDATA_JOHTO, &list_siz );
	}else{
		list = SortDataLoad( ZKN_SORTDATA_ZENKOKU, &list_siz );
	}
	SeeMonsDataMake( make0, &make0_cnt, wk->dat->zukan_work, list, list_siz );

	// ソート
	ListSort( sort, make1, &make1_cnt, make0, make0_cnt, wk->dat->zukan_work );
	memcpy( make0, make1, sizeof(u16) * make1_cnt );
	make0_cnt = make1_cnt;
	memset( make1, 0, sizeof(u16) * make1_cnt );
	make1_cnt = 0;

	do{
		// 名前検索
		NameSearch( name, make1, &make1_cnt, make0, make0_cnt, wk->dat->zukan_work );
		if( make1_cnt == 0 ){
			ret = FALSE;
			break;
		}
		memcpy( make0, make1, sizeof(u16) * make1_cnt );
		make0_cnt = make1_cnt;
		memset( make1, 0, sizeof(u16) * make1_cnt );
		make1_cnt = 0;

		// タイプ１検索
		TypeSearch( type1, make1, &make1_cnt, make0, make0_cnt, wk->dat->zukan_work );
		if( make1_cnt == 0 ){
			ret = FALSE;
			break;
		}
		memcpy( make0, make1, sizeof(u16) * make1_cnt );
		make0_cnt = make1_cnt;
		memset( make1, 0, sizeof(u16) * make1_cnt );
		make1_cnt = 0;

		// タイプ２検索
		TypeSearch( type2, make1, &make1_cnt, make0, make0_cnt, wk->dat->zukan_work );
		if( make1_cnt == 0 ){
			ret = FALSE;
			break;
		}
		memcpy( make0, make1, sizeof(u16) * make1_cnt );
		make0_cnt = make1_cnt;
		memset( make1, 0, sizeof(u16) * make1_cnt );
		make1_cnt = 0;

		// 形検索
		FormSearch( form, make1, &make1_cnt, make0, make0_cnt, wk->dat->zukan_work );
		if( make1_cnt == 0 ){
			ret = FALSE;
			break;
		}
		memcpy( make0, make1, sizeof(u16) * make1_cnt );
		make0_cnt = make1_cnt;
		memset( make1, 0, sizeof(u16) * make1_cnt );
		make1_cnt = 0;

		// 地域検索
		// 全国図鑑未オープン時、エリアが不明なら、カントーのポケモンもセットする
		if( wk->zenkoku_mode == FALSE && ( area & ZKN2LIST_SEARCH_AREA_MASK_ETC ) != 0 ){
			AreaSearch(
				wk, ( ZKN2LIST_SEARCH_AREA_MASK_KANTO | ZKN2LIST_SEARCH_AREA_MASK_ETC ),
				make1 ,&make1_cnt, make0, make0_cnt, wk->dat->zukan_work );
			if( make1_cnt == 0 ){
				ret = FALSE;
				break;
			}
		}else{
			AreaSearch( wk, area, make1, &make1_cnt, make0, make0_cnt, wk->dat->zukan_work );
			if( make1_cnt == 0 ){
				ret = FALSE;
				break;
			}
		}
		memcpy( make0, make1, sizeof(u16) * make1_cnt );
		make0_cnt = make1_cnt;
		memset( make1, 0, sizeof(u16) * make1_cnt );
		make1_cnt = 0;

		// 高さ
		HeightSearch( wk, hLow, hHi, make1, &make1_cnt, make0, make0_cnt, wk->dat->zukan_work );
		memcpy( make0, make1, sizeof(u16) * make1_cnt );
		make0_cnt = make1_cnt;
		memset( make1, 0, sizeof(u16) * make1_cnt );
		make1_cnt = 0;

		// 重さ
		WeightSearch( wk, wLow, wHi, make1, &make1_cnt, make0, make0_cnt, wk->dat->zukan_work );

		// 最終的なリストを作成
		ListMakeFinal( &wk->mons_list, wk->dat->zukan_work, make1, make1_cnt );

		ret = TRUE;

	}while(0);

	sys_FreeMemoryEz( list );
	sys_FreeMemoryEz( make1 );
	sys_FreeMemoryEz( make0 );

	return TRUE;
}

//--------------------------------------------------------------------------------------------
/**
 *	ソートリストデータ読み込み
 *
 *	@param	idx			データインデックス
 *	@param	max			配列数取得場所
 *
 *	@return	読み込みデータバッファ
 *
 *	ZKN_SORTDATA_Get()
 */
//--------------------------------------------------------------------------------------------
static u16 * SortDataLoad( u32 idx, u32 * max )
{
	u16 * buf;
	u32	siz;

	GF_ASSERT( ZKN_SORTDATA_MAX > idx );

	// 読み込み
	buf = ArcUtil_LoadEx(
			ZKN_GIRA_GetZukanDataArcIdx(),
			NARC_zukan_data_zkn_sort_zenkoku_dat + idx,
			FALSE,
			HEAPID_ZUKAN,
			ALLOC_TOP,
			&siz );

	*max = siz / sizeof(u16);

	return buf;
}

//--------------------------------------------------------------------------------------------
/**
 *	リストから見たことのあるポケモンを取得
 *
 *	@param	make	データ作成先
 *	@param	cnt		データカウント
 *	@param	sv		図鑑セーブデータ
 *	@param	list	リスト
 *	@param	num		リストカウント
 *
 *	@return	none
 *
 *	ZknPokeListTblMakeSortData()
 */
//--------------------------------------------------------------------------------------------
static void SeeMonsDataMake( u16 * make, u32 * cnt, const ZUKAN_WORK * sv, const u16 * list, u32 num )
{
	u32	i;

	*cnt = 0;

	for( i=0; i<num; i++ ){
		if( ZukanWork_GetPokeSeeFlag( sv, list[i] ) ){
			make[*cnt] = list[i];
			(*cnt) ++;
		}
	}
}

//--------------------------------------------------------------------------------------------
/**
 *	最終的なリストを作成
 *
 *	@param	list	作成先
 *	@param	sv		図鑑セーブデータ
 *	@param	tbl		見つけたポケモンのソート済みテーブル
 *	@param	num		テーブル数
 *
 *	@return	none
 */
//--------------------------------------------------------------------------------------------
static void ListMakeFinal( ZKN2_LIST * list, const ZUKAN_WORK * sv, const u16 * tbl, int num )
{
	u32	i;

	list->see_num = num;
	list->get_num = 0;

	for( i=0; i<num; i++ ){
		list->dat[i].mons = tbl[i];
		if( ZukanWork_GetPokeGetFlag( sv, tbl[i] ) ){
			list->dat[i].type = ZKN2LIST_REGTYPE_GET;
			list->get_num++;
		}else{
			list->dat[i].type = ZKN2LIST_REGTYPE_SEE;
		}
	}
}

//--------------------------------------------------------------------------------------------
/**
 *	ソート処理
 *
 *	@param	type		ソートタイプ
 *	@param	make		データ作成先
 *	@param	cnt			データカウント
 *	@param	list		元データ
 *	@param	num			元データ数
 *	@param	sv			図鑑セーブデータ
 *
 *	@return	none
 *
 *	ZknPokeListSort_Core()
 */
//--------------------------------------------------------------------------------------------
static void ListSort( u32 type, u16 * make, u32 * cnt, const u16 * list, u32 num, const ZUKAN_WORK * sv )
{
	u16 * dat;
	u32	dat_cnt;
	BOOL see_ok_flg = FALSE;

	switch( type ){
	case ZKN2LIST_SORT_NORMAL:		// ポケモンナンバー
		memcpy( make, list, sizeof(u16) * num );
		*cnt = num;
		return;

	case ZKN2LIST_SORT_GOZYUUON:	// 五十音
		dat = SortDataLoad( ZKN_SORTDATA_AIUEO, &dat_cnt );
		see_ok_flg = TRUE;
		break;

	case ZKN2LIST_SORT_GRAM_L:		// 重い
		dat = SortDataLoad( ZKN_SORTDATA_HEAVY, &dat_cnt );
		break;

	case ZKN2LIST_SORT_GRAM_S:		// 軽い
		dat = SortDataLoad( ZKN_SORTDATA_LIGHT, &dat_cnt );
		break;

	case ZKN2LIST_SORT_HIGH_L:		// 高い
		dat = SortDataLoad( ZKN_SORTDATA_TALL, &dat_cnt );
		break;

	case ZKN2LSIT_SOTT_HIGH_S:		// 低い
		dat = SortDataLoad( ZKN_SORTDATA_SMALL, &dat_cnt );
		break;

	default:
		GF_ASSERT(0);
	}

	ListSearch( make, cnt, list, num, dat, dat_cnt, see_ok_flg, sv );
	sys_FreeMemoryEz( dat );
}

//--------------------------------------------------------------------------------------------
/**
 *	名前検索
 *
 *	@param	type		検索タイプ
 *	@param	make		データ作成先
 *	@param	cnt			データカウント
 *	@param	list		元データ
 *	@param	num			元データ数
 *	@param	sv			図鑑セーブデータ
 *
 *	@return	none
 */
//--------------------------------------------------------------------------------------------
static void NameSearch( u32 type, u16 * make, u32 * cnt, const u16 * list, u32 num, const ZUKAN_WORK * sv )
{
	u16 * dat;
	u32	dat_cnt;

	switch( type ){
	case ZKN2LIST_SEARCH_NAME_NONE:
		memcpy( make, list, sizeof(u16) * num );
		*cnt = num;
		return;

	default:
		dat = SortDataLoad( ZKN_SORTDATA_NAME_A+type, &dat_cnt );
		break;
	}

	ListSearch( make, cnt, dat, dat_cnt, list, num, TRUE, sv );
	sys_FreeMemoryEz( dat );
}

//--------------------------------------------------------------------------------------------
/**
 *	タイプ検索
 *
 *	@param	type		検索タイプ
 *	@param	make		データ作成先
 *	@param	cnt			データカウント
 *	@param	list		元データ
 *	@param	num			元データ数
 *	@param	sv			図鑑セーブデータ
 *
 *	@return	none
 */
//--------------------------------------------------------------------------------------------
static void TypeSearch( u32 type, u16 * make, u32 * cnt, const u16 * list, int num, const ZUKAN_WORK * sv )
{
	u16 * dat;
	u32	dat_cnt;
	int sort_data_count;

	switch( GetSearchIDType(type) ){
	case ZKN2LIST_SEARCH_TYPE_NONE:
		memcpy( make, list, sizeof(u16) * num );
		*cnt = num;
		return;

	case ZKN2LIST_SEARCH_TYPE_NORMAL:
		dat = SortDataLoad( ZKN_SORTDATA_TYPE_NORMAL, &dat_cnt );
		break;
	case ZKN2LIST_SEARCH_TYPE_BATTLE:
		dat = SortDataLoad( ZKN_SORTDATA_TYPE_BATTLE, &dat_cnt );
		break;
	case ZKN2LIST_SEARCH_TYPE_HIKOU:
		dat = SortDataLoad( ZKN_SORTDATA_TYPE_HIKOU, &dat_cnt );
		break;
	case ZKN2LIST_SEARCH_TYPE_POISON:
		dat = SortDataLoad( ZKN_SORTDATA_TYPE_POISON, &dat_cnt );
		break;
	case ZKN2LIST_SEARCH_TYPE_JIMEN:
		dat = SortDataLoad( ZKN_SORTDATA_TYPE_JIMEN, &dat_cnt );
		break;
	case ZKN2LIST_SEARCH_TYPE_IWA:
		dat = SortDataLoad( ZKN_SORTDATA_TYPE_IWA, &dat_cnt );
		break;
	case ZKN2LIST_SEARCH_TYPE_MUSHI:
		dat = SortDataLoad( ZKN_SORTDATA_TYPE_MUSHI, &dat_cnt );
		break;
	case ZKN2LIST_SEARCH_TYPE_GHOST:
		dat = SortDataLoad( ZKN_SORTDATA_TYPE_GHOST, &dat_cnt );
		break;
	case ZKN2LIST_SEARCH_TYPE_METAL:
		dat = SortDataLoad( ZKN_SORTDATA_TYPE_METAL, &dat_cnt );
		break;
	case ZKN2LIST_SEARCH_TYPE_FIRE:
		dat = SortDataLoad( ZKN_SORTDATA_TYPE_FIRE, &dat_cnt );
		break;
	case ZKN2LIST_SEARCH_TYPE_WATER:
		dat = SortDataLoad( ZKN_SORTDATA_TYPE_WATER, &dat_cnt );
		break;
	case ZKN2LIST_SEARCH_TYPE_KUSA:
		dat = SortDataLoad( ZKN_SORTDATA_TYPE_KUSA, &dat_cnt );
		break;
	case ZKN2LIST_SEARCH_TYPE_ELECTRIC:
		dat = SortDataLoad( ZKN_SORTDATA_TYPE_ELECTRIC, &dat_cnt );
		break;
	case ZKN2LIST_SEARCH_TYPE_SP:
		dat = SortDataLoad( ZKN_SORTDATA_TYPE_SP, &dat_cnt );
		break;
	case ZKN2LIST_SEARCH_TYPE_KOORI:
		dat = SortDataLoad( ZKN_SORTDATA_TYPE_KOORI, &dat_cnt );
		break;
	case ZKN2LIST_SEARCH_TYPE_DRAGON:
		dat = SortDataLoad( ZKN_SORTDATA_TYPE_DRAGON, &dat_cnt );
		break;
	case ZKN2LIST_SEARCH_TYPE_AKU:
		dat = SortDataLoad( ZKN_SORTDATA_TYPE_AKU, &dat_cnt );
		break;

	default:
		GF_ASSERT(0);
	}

	ListSearch( make, cnt, dat, dat_cnt, list, num, FALSE, sv );
	sys_FreeMemoryEz( dat );
}

//--------------------------------------------------------------------------------------------
/**
 *	形検索
 *
 *	@param	type		検索タイプ
 *	@param	make		データ作成先
 *	@param	cnt			データカウント
 *	@param	list		元データ
 *	@param	num			元データ数
 *	@param	sv			図鑑セーブデータ
 *
 *	@return	none
 */
//--------------------------------------------------------------------------------------------
static void FormSearch( u32 type, u16 * make, u32 * cnt, const u16 * list, u32 num, const ZUKAN_WORK * sv )
{
	u16 * dat;
	u32	dat_cnt;

	switch( type ){
	case ZKN2LIST_SEARCH_FORM_NONE:
		memcpy( make, list, sizeof(u16) * num );
		*cnt = num;
		return;

	case ZKN2LIST_SEARCH_FORM_FOUR_LEGS:
		dat = SortDataLoad( ZKN_SORTDATA_FORM_FOUR_LEGS, &dat_cnt );
		break;
	case ZKN2LIST_SEARCH_FORM_TWO_LEGS:
		dat = SortDataLoad( ZKN_SORTDATA_FORM_TWO_LEGS, &dat_cnt );
		break;
	case ZKN2LIST_SEARCH_FORM_TAIL:
		dat = SortDataLoad( ZKN_SORTDATA_FORM_TAIL, &dat_cnt );
		break;
	case ZKN2LIST_SEARCH_FORM_HARABAI:
		dat = SortDataLoad( ZKN_SORTDATA_FORM_HARABAI, &dat_cnt );
		break;
	case ZKN2LIST_SEARCH_FORM_FOUR_WING:
		dat = SortDataLoad( ZKN_SORTDATA_FORM_FOUR_WING, &dat_cnt );
		break;
	case ZKN2LIST_SEARCH_FORM_TWO_WING:
		dat = SortDataLoad( ZKN_SORTDATA_FORM_TWO_WING, &dat_cnt );
		break;
	case ZKN2LIST_SEARCH_FORM_HAITSUKUBARI:
		dat = SortDataLoad( ZKN_SORTDATA_FORM_HAITSUKUBARI, &dat_cnt );
		break;
	case ZKN2LIST_SEARCH_FORM_STRAIGHT:
		dat = SortDataLoad( ZKN_SORTDATA_FORM_STRAIGHT, &dat_cnt );
		break;
	case ZKN2LIST_SEARCH_FORM_ARM:
		dat = SortDataLoad( ZKN_SORTDATA_FORM_ARM, &dat_cnt );
		break;
	case ZKN2LIST_SEARCH_FORM_LEGS:
		dat = SortDataLoad( ZKN_SORTDATA_FORM_LEGS, &dat_cnt );
		break;
	case ZKN2LIST_SEARCH_FORM_MANY_LEGS:
		dat = SortDataLoad( ZKN_SORTDATA_FORM_MANY_LEGS, &dat_cnt );
		break;
	case ZKN2LIST_SEARCH_FORM_WATER:
		dat = SortDataLoad( ZKN_SORTDATA_FORM_WATER, &dat_cnt );
		break;
	case ZKN2LIST_SEARCH_FORM_CIRCLE:
		dat = SortDataLoad( ZKN_SORTDATA_FORM_CIRCLE, &dat_cnt );
		break;
	case ZKN2LIST_SEARCH_FORM_COMP:
		dat = SortDataLoad( ZKN_SORTDATA_FORM_COMP, &dat_cnt );
		break;
	default:
		GF_ASSERT(0);
	}

	ListSearch( make, cnt, dat, dat_cnt, list, num, TRUE, sv );
	sys_FreeMemoryEz( dat );
}

//--------------------------------------------------------------------------------------------
/**
 *	地域検索
 *
 *	@param	wk			図鑑画面ワーク
 *	@param	type		検索タイプ
 *	@param	make		データ作成先
 *	@param	cnt			データカウント
 *	@param	list		元データ
 *	@param	num			元データ数
 *	@param	sv			図鑑セーブデータ
 *
 *	@return	none
 */
//--------------------------------------------------------------------------------------------
static void AreaSearch(
				ZKN2_WORK * wk, u32 type,
				u16 * make, u32 * cnt, const u16 * list, u32 num, const ZUKAN_WORK * sv )
{
	if( type & ZKN2LIST_SEARCH_AREA_MASK_NONE ){
		memcpy( make, list, sizeof(u16) * num );
		*cnt = num;
	}else{
		u32	i;
		// 全国未オープンで「ふめい」のとき
		if( type == (ZKN2LIST_SEARCH_AREA_MASK_KANTO|ZKN2LIST_SEARCH_AREA_MASK_ETC) ){
			for( i=0; i<num; i++ ){
				if( ( wk->area_dat[list[i]] & type ) == 0 ||
					( wk->area_dat[list[i]] & ZKN2LIST_SEARCH_AREA_MASK_JHOTO ) != 0 ||
					ZukanWork_GetPokeSeeFlag( sv, list[i] ) == 0 ){
					continue;
				}
				make[*cnt] = list[i];
				(*cnt)++;
			}
		}else{
			for( i=0; i<num; i++ ){
				if( ( wk->area_dat[list[i]] & type ) == 0 ||
					ZukanWork_GetPokeSeeFlag( sv, list[i] ) == 0 ){
					continue;
				}
				make[*cnt] = list[i];
				(*cnt)++;
			}
		}
	}
}

//--------------------------------------------------------------------------------------------
/**
 *	高さ検索
 *
 *	@param	wk			図鑑画面ワーク
 *	@param	low			高さ（低）
 *	@param	hi			高さ（高）
 *	@param	make		データ作成先
 *	@param	cnt			データカウント
 *	@param	list		元データ
 *	@param	num			元データ数
 *	@param	sv			図鑑セーブデータ
 *
 *	@return	none
 */
//--------------------------------------------------------------------------------------------
static void HeightSearch(
				ZKN2_WORK * wk, u16 low, u16 hi,
				u16 * make, u32 * cnt, const u16 * list, u32 num, const ZUKAN_WORK * sv )
{
	if( low == 0 && hi == ZKN2_HW_DOT_MAX ){
		memcpy( make, list, sizeof(u16) * num );
		*cnt = num;
	}else{
		u32	i;

		for( i=0; i<num; i++ ){
			if( wk->mons_height[list[i]] >= wk->hw_dot[low].height &&
				wk->mons_height[list[i]] <= wk->hw_dot[hi].height &&
				ZukanWork_GetPokeGetFlag( sv, list[i] ) != 0 ){

				make[*cnt] = list[i];
				(*cnt)++;
			}
		}
	}
}

//--------------------------------------------------------------------------------------------
/**
 *	重さ検索
 *
 *	@param	wk			図鑑画面ワーク
 *	@param	low			重さ（低）
 *	@param	hi			重さ（高）
 *	@param	make		データ作成先
 *	@param	cnt			データカウント
 *	@param	list		元データ
 *	@param	num			元データ数
 *	@param	sv			図鑑セーブデータ
 *
 *	@return	none
 */
//--------------------------------------------------------------------------------------------
static void WeightSearch(
				ZKN2_WORK * wk, u16 low, u16 hi,
				u16 * make, u32 * cnt, const u16 * list, u32 num, const ZUKAN_WORK * sv )
{
	if( low == 0 && hi == ZKN2_HW_DOT_MAX ){
		memcpy( make, list, sizeof(u16) * num );
		*cnt = num;
	}else{
		u32	i;

		for( i=0; i<num; i++ ){
			if( wk->mons_weight[list[i]] >= wk->hw_dot[low].weight &&
				wk->mons_weight[list[i]] <= wk->hw_dot[hi].weight &&
				ZukanWork_GetPokeGetFlag( sv, list[i] ) != 0 ){

				make[*cnt] = list[i];
				(*cnt)++;
			}
		}
	}
}


//--------------------------------------------------------------------------------------------
/**
 *	ソートリストから見た/ゲットしたポケモンをサーチ
 *
 *	@param	make		データ作成先
 *	@param	cnt			データカウント
 *	@param	list		ソートリスト
 *	@param	list_num	ソートリスト数
 *	@param	search		サーチテーブル
 *	@param	search_num	サーチテーブル数
 *	@param	see_ok_flg	見ただけポケモンもOKかチェック
 *	@param	sv			図鑑セーブデータ
 *
 *	@return	none
 *
 *	ZknPokeListTblMakeSarch()
 */
//--------------------------------------------------------------------------------------------
static void ListSearch( u16 * make, u32 * cnt, const u16 * list, u32 list_num, const u16 * search, u32 search_num, BOOL see_ok_flg, const ZUKAN_WORK * sv )
{
	u32	i, j;

	*cnt = 0;

	// 見たことがあるだけで良い場合
	if( see_ok_flg == TRUE ){
		for( i=0; i<search_num; i++ ){
			for( j=0; j<list_num; j++ ){
				if( search[i] == list[j] ){
					make[*cnt] = search[i];
					(*cnt) ++;
					break;
				}
			}
		}
	}else{
		for( i=0; i<search_num; i++ ){
			for( j=0; j<list_num; j++ ){
				if( search[i] == list[j] ){
					if( ZukanWork_GetPokeGetFlag( sv, search[i] ) ){
						make[*cnt] = search[i];
						(*cnt) ++;
						break;
					}
				}
			}
		}
	}
}

//--------------------------------------------------------------------------------------------
/**
 * 選択位置を取得
 *
 * @param	wk		図鑑画面ワーク
 *
 * @return	選択位置
 */
//--------------------------------------------------------------------------------------------
u32 ZKN2LIST_SelPosGet( ZKN2_WORK * wk )
{
	return ( wk->list_scr * ZKN2_POKEICON_SEL_MAX + wk->list_pos );
}

//--------------------------------------------------------------------------------------------
/**
 * 選択位置のポケモンを取得
 *
 * @param	wk		図鑑画面ワーク
 *
 * @return	初期位置のポケモン
 */
//--------------------------------------------------------------------------------------------
u16 ZKN2LIST_SelMonsGet( ZKN2_WORK * wk )
{
	return wk->list_put[ ZKN2LIST_SelPosGet(wk) ].mons;
}


//--------------------------------------------------------------------------------------------
/**
 *	初期位置のポケモンの存在をチェック
 *
 *	@param	list		リストデータ
 *	@param	mons		初期位置のポケモン
 *
 *	@return	初期位置のポケモン
 */
//--------------------------------------------------------------------------------------------
u16 ZKN2LIST_StartMonsCheck( ZKN2_LIST * list, u16 mons )
{
	u32	i;
	u16	start;

	start = 0;
	for( i=0; i<list->see_num; i++ ){
		if( start == 0 ){
			start = list->dat[i].mons;
		}
		if( list->dat[i].mons == mons ){
			return mons;
		}
	}
	return start;
}

//--------------------------------------------------------------------------------------------
/**
 * リストページ表示用データ作成
 *
 * @param	wk			図鑑画面ワーク
 *
 * @return	none
 */
//--------------------------------------------------------------------------------------------
void ZKN2LIST_ListPutMake( ZKN2_WORK * wk, BOOL space )
{
	u32	i;
	u32	no;

	MI_CpuClear32( (void*)wk->list_put, sizeof(ZKN2_POKE_DATA)*ZKN2_POKELIST_PUT_MAX );

	if( space == TRUE ){
		for( i=0; i<wk->mons_list.see_num; i++ ){
			no = PMNumber_GetPokeNumber( wk->zkn_mode, wk->mons_list.dat[i].mons ) - 1;

			wk->list_put[no].mons = wk->mons_list.dat[i].mons;
			wk->list_put[no].type = wk->mons_list.dat[i].type;
		}
	}else{
		for( i=0; i<wk->mons_list.see_num; i++ ){
			wk->list_put[i+1].mons = wk->mons_list.dat[i].mons;
			wk->list_put[i+1].type = wk->mons_list.dat[i].type;
		}
	}
}

//--------------------------------------------------------------------------------------------
/**
 * 確認したポケモンの最後の図鑑番号を取得
 *
 * @param	wk		図鑑画面ワーク
 *
 * @return	最後の図鑑番号
 */
//--------------------------------------------------------------------------------------------
u32 ZKN2LIST_ListMaxGet( ZKN2_WORK * wk, BOOL space )
{
	if( space == FALSE ){
		return wk->mons_list.see_num;
	}
	return PMNumber_GetPokeNumber( wk->zkn_mode, wk->mons_list.dat[wk->mons_list.see_num-1].mons );
}

//--------------------------------------------------------------------------------------------
/**
 * リストページのスクロール最大値を取得
 *
 * @param	wk		図鑑画面ワーク
 *
 * @return	スクロール最大値
 */
//--------------------------------------------------------------------------------------------
u32 ZKN2LIST_ListScrollMaxGet( ZKN2_WORK * wk, BOOL space )
{
	if( space == FALSE ){
		return ( ZKN2LIST_ListMaxGet(wk,space) / ZKN2_POKEICON_SEL_MAX );
	}
	return ( (ZKN2LIST_ListMaxGet(wk,space)-1) / ZKN2_POKEICON_SEL_MAX );
}

//--------------------------------------------------------------------------------------------
/**
 * 検索用タイプ取得
 *
 * @param	p	タイプリスト位置
 *
 * @return	検索用タイプ
 */
//--------------------------------------------------------------------------------------------
static u32 GetSearchIDType( u32 p )
{
	return SearchTypeTbl[p];
}